#include "../inc/skyTrace.h"

namespace Sky
{
	#pragma warning(disable:4996)
	

	//////////////////////////////////////////////////////////////////////////
	#if defined(_XTRACE_LOGFILE)
		static HANDLE _xlogfp;
		static TAchar _xlogfile[MAX_PATH];
		class xCLog
		{
		public:
			xCLog(void);
			xCLog(TUint dirlen,const TAchar* dir);
			xCLog(TUint dirlen,const TWchar* dir);
			~xCLog(void);
		};
		xCLog::xCLog(void)
		{
			StringCchCatA(_xlogfile,MAX_PATH-1,("debug.txt"));
			/*_xlogfp=fopen(_xlogfile,"w");*/
			_xlogfp = CreateFileA(_xlogfile,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
			xAssertA(_xlogfp!=vNull && "Can't open debug.txt");
		}
		xCLog::xCLog(TUint dirlen,const TAchar* dir)
		{
			xAssertA(dirlen>MAX_PATH && ("Debug dir too long"));
			StringCchCatA(_xlogfile,dirlen,dir);
			//_xlogfp=fopen(_xlogfile,"w");
			_xlogfp = CreateFileA(_xlogfile,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
			xAssertA(_xlogfp!=vNull && ("Can't open debug.txt"));
		}
		xCLog::~xCLog(void)
		{
			//fclose(_xlogfp);
			if(_xlogfp != vNull)
				CloseHandle(_xlogfp);
		}
		static xCLog _xlog;
		void xLog(const TAchar* pFmt,...)
		{
			TAchar sz[512];
			va_list va;
			va_start(va,pFmt);
			StringCchVPrintfA(sz,sizeof(sz),pFmt,va);
			va_end(va);

			_xlogfp = CreateFileA(_xlogfile,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
			if(_xlogfp != vNull)
			{
				//fwrite(sz,strlen(sz),1,_xlogfp);
				TUint32 written;
				WriteFile(_xlogfp,sz,(TUint)strlen(sz),&written,vNull);
				CloseHandle(_xlogfp);
			}
		}
	#else
			void xLog(const TChar* pFmt,...){}
	#endif
	//////////////////////////////////////////////////////////////////////////
	#if defined(_XTRACE_OUTCONSOLE)
		static HANDLE _xhcon;
		class xCOut
		{
		public:
			xCOut(void);
			~xCOut(void);
		};
		xCOut::xCOut(void)
		{
			AllocConsole();
			_xhcon=GetStdHandle(STD_OUTPUT_HANDLE);
			xAssertA(_xhcon!=INVALID_HANDLE_VALUE&&"Can't open console");
		}
		xCOut::~xCOut(void)
		{
			CloseHandle(_xhcon);  
			FreeConsole();     
		}
		static xCOut _xcout;
		void xOut(const TChar* pFmt,...)
		{
			TChar sz[512];
			va_list va;
			va_start(va, pFmt);
			StringCchVPrintf(sz,sizeof(sz),pFmt,va);
			va_end(va);
			TUint32 cWritten;
			if(_xhcon!=INVALID_HANDLE_VALUE)
			{
				WriteConsole(_xhcon, sz, (TUint)skyStrlen(sz), &cWritten, vNull);
			}
		}
	#else
			void xOut(const TChar* pFmt,...){}
	#endif
	//////////////////////////////////////////////////////////////////////////
	#if defined(_XTRACE_DBGCONSOLE)
		void xDbg(const TChar *pFormat,...)
		{
			TChar sz[512];
			va_list va;
			va_start(va,pFormat);
			StringCchVPrintf(sz,sizeof(sz),pFormat,va);
			va_end(va);
			OutputDebugString( sz );
		}
	#endif
	//////////////////////////////////////////////////////////////////////////
	#if defined(_XTRACE_MSGBOX)
		TVoid xMessageBox(const TChar* pFmt,...)
		{
			TChar sz[512];
			va_list va;
			va_start(va,pFmt);
			StringCchVPrintf(sz,sizeof(sz),pFmt,va);
			va_end(va);
			MessageBox(vNull,sz,_XT("xMessageBox"),MB_OK);
		}
	#else
		TVoid xMessageBox(const TChar* pFmt,...){}
	#endif
	//////////////////////////////////////////////////////////////////////////
	#if defined(_XTRACE)
	TVoid doTraceW(xTraceType type,const TWchar* sz)
	{
	#if defined(_XTRACE_OUTCONSOLE)
		if((type & eType_OutConsol) != 0)
		{
			TUint32 cWritten;
			if(_xhcon!=INVALID_HANDLE_VALUE)
			{
				::WriteConsoleW(_xhcon, sz, (TUint)wcslen(sz), &cWritten, vNull);
			}
		} // if((type & xOutConsol) != 0)
	#endif
	#if defined(_XTRACE_DBGCONSOLE)
		if((type & eType_DbgConsol) != 0)
		{
			::OutputDebugStringW( sz );
		}
	#endif
	#if defined(_XTRACE_LOGFILE)
		if((type & eType_LogFile) != 0)
		{
			HANDLE file;
			file = CreateFileA(("trace.txt"),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
			if(file != INVALID_HANDLE_VALUE)
			{
				//fwrite(sz,strlen(sz),1,_xlogfp);
				TUint32 written;
				::WriteFile(file,sz,(TUint)wcslen(sz),&written,vNull);
				::CloseHandle(file);
			} // if(file != INVALID_HANDLE_VALUE)
		} // if((type & xTraceType::xLogFile) != 0)
	#endif
	#if defined(_XTRACE_MSGBOX)
		if((type & eType_MsgBox) != 0)
		{ 
			MessageBoxW(vNull,sz,L"trace",MB_OK);
		}
	#endif
	#if defined(_XTRACE_ASSERT)
		if((type & eType_DxAssert) != 0)
		{
#ifdef D3D9_INCLUDE
			DXTraceW(NULL,0,0,sz,vTrue);
#endif
			
		}
		else if((type & eType_AssertBox) != 0)
		{
			assert(0&&(char*)sz);
		}
		
	#endif
		return ;
	}

	TVoid doTraceA(xTraceType type,const TAchar* sz)
	{
#if defined(_XTRACE_OUTCONSOLE)
		if((type & eType_OutConsol) != 0)
		{
			TUint32 cWritten;
			if(_xhcon!=INVALID_HANDLE_VALUE)
			{
				::WriteConsoleA(_xhcon, sz, (TUint)strlen(sz), &cWritten, vNull);
			}
		} // if((type & xOutConsol) != 0)
#endif
#if defined(_XTRACE_DBGCONSOLE)
		if((type & eType_DbgConsol) != 0)
		{
			::OutputDebugStringA( sz );
		}
#endif
#if defined(_XTRACE_LOGFILE)
		if((type & eType_LogFile) != 0)
		{
			HANDLE file;
			file = CreateFileA(("trace.txt"),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)vNull,OPEN_ALWAYS ,0,vNull);
			if(file != INVALID_HANDLE_VALUE)
			{
				//fwrite(sz,strlen(sz),1,_xlogfp);
				TUint32 written;
				::WriteFile(file,sz,(TUint)strlen(sz),&written,vNull);
				::CloseHandle(file);
			} // if(file != INVALID_HANDLE_VALUE)
		} // if((type & xTraceType::xLogFile) != 0)
#endif
#if defined(_XTRACE_MSGBOX)
		if((type & eType_MsgBox) != 0)
		{ 
			MessageBoxA(vNull,sz,"trace",MB_OK);
		}
#endif
#if defined(_XTRACE_ASSERT)
		if((type & eType_DxAssert) != 0)
		{
#ifdef D3D9_INCLUDE
			DXTraceA(NULL,0,0,sz,vTrue);
#endif
		}
		else if((type & eType_AssertBox) != 0)
		{
			assert(0&&(char*)sz);
		}

#endif
		return ;
	}

	TVoid xTraceW(xTraceType type,TUint errLevel,const TWchar* fmt,...)
	{
		TWchar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfW(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceW(type,sz);
	}
	TResult xTraceHrW(xTraceType type,TUint traceLevel,TResult hr,const TWchar* fmt,...)
	{
		TWchar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfW(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceW(type,sz);
		return hr;
	}

	TVoid xTraceA(xTraceType type,TUint errLevel,const TAchar* fmt,...)
	{
		TAchar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfA(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceA(type,sz);
	}
	TResult xTraceHrA(xTraceType type,TUint traceLevel,TResult hr,const TAchar* fmt,...)
	{
		TAchar sz[512];
		va_list va;
		va_start(va, fmt);
		StringCchVPrintfA(sz,sizeof(sz),fmt,va);
		va_end(va);
		doTraceA(type,sz);
		return hr;
	}

	#else
		TVoid	xTraceW(xTraceType type,TUint traceLevel,const TChar* fmt,...)	{;}
		TResult xTraceHrW(xTraceType type,TUint traceLevel,TResult hr,const TChar* fmt,...)	{return hr;}
		TVoid	xTraceA(xTraceType type,TUint traceLevel,const TChar* fmt,...)	{;}
		TResult xTraceHrA(xTraceType type,TUint traceLevel,TResult hr,const TChar* fmt,...)	{return hr;}
	#endif

	#pragma warning(default:4996)
}//NLib
